package de.ipk_gatersleben.bit.bi.edal.publication.metadata;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.JProgressBar;

public class FileProgressInputStream extends FilterInputStream {

	private FileProgressMonitor monitor;
	private int nread = 0;
	private int size = 0;
	private JProgressBar fileProgressBar;

	/**
	 * Constructs an object to monitor the progress of an input stream.
	 * 
	 * @param inputStream
	 *            The input stream to be monitored.
	 */
	public FileProgressInputStream(JProgressBar fileProgressBar,
			InputStream inputStream) {
		super(inputStream);
		this.fileProgressBar = fileProgressBar;
		try {
			size = inputStream.available();
		} catch (IOException ioe) {
			size = 0;
		}

		this.monitor = new FileProgressMonitor(this.fileProgressBar, size);
	}

	/**
	 * Get the ProgressMonitor object being used by this stream. Normally this
	 * isn't needed unless you want to do something like change the descriptive
	 * text partway through reading the file.
	 * 
	 * @return the ProgressMonitor object used by this object
	 */
	public FileProgressMonitor getProgressMonitor() {
		return this.monitor;
	}

	/**
	 * Overrides <code>FilterInputStream.read</code> to update the progress
	 * monitor after the read.
	 */
	public int read() throws IOException {
		int c = in.read();
		if (c >= 0)
			this.monitor.setProgress(++nread);

		return c;
	}

	/**
	 * Overrides <code>FilterInputStream.read</code> to update the progress
	 * monitor after the read.
	 */
	public int read(byte b[]) throws IOException {
		int nr = in.read(b);
		if (nr > 0)
			this.monitor.setProgress(nread += nr);
		return nr;
	}

	/**
	 * Overrides <code>FilterInputStream.read</code> to update the progress
	 * monitor after the read.
	 */
	public int read(byte b[], int off, int len) throws IOException {
		int nr = in.read(b, off, len);
		if (nr > 0)
			monitor.setProgress(nread += nr);
		return nr;
	}

	/**
	 * Overrides <code>FilterInputStream.skip</code> to update the progress
	 * monitor after the skip.
	 */
	public long skip(long n) throws IOException {
		long nr = in.skip(n);
		if (nr > 0)
			monitor.setProgress(nread += nr);
		return nr;
	}

	/**
	 * Overrides <code>FilterInputStream.close</code> to close the progress
	 * monitor as well as the stream.
	 */
	public void close() throws IOException {
		in.close();
		monitor.close();
	}

	/**
	 * Overrides <code>FilterInputStream.reset</code> to reset the progress
	 * monitor as well as the stream.
	 */
	public synchronized void reset() throws IOException {
		in.reset();
		nread = size - in.available();
		monitor.setProgress(nread);
	}
}